import json
import re
import uuid
from random import random

import requests
from django.contrib.auth.hashers import make_password, check_password
from django.core.cache import cache
from rest_framework import serializers

from users.models import UserModel
from utils.errors import ParamsException


PASSWORD_PATTERN = re.compile(r'[1-9a-zA-Z]')


class UserSerializer(serializers.ModelSerializer):

    class Meta:
        # 序列化的模型
        model = UserModel
        #  序列化的字段
        fields = '__all__'


class RegisterSerializer(serializers.Serializer):
    # 注册参数序列化
    user_tel = serializers.CharField(max_length=11, min_length=11,
                                       required=True,
                                       error_messages={
                                           'required': '手机号码必填',
                                           'max_length': '请输入正确手机号码',
                                           'min_length': '请输入正确手机号码'
                                       })
    tel_code = serializers.CharField(max_length=6, min_length=6,
                                       error_messages={
                                           'max_length': '请输入正确验证码',
                                           'min_length': '请输入正确验证码'
                                       })

    def validate(self, attrs):
        # 校验账号字段是否已存在
        tel = attrs.get('user_tel')
        user = UserModel.objects.filter(user_tel=tel).first()
        if user:
            # 账号已存在，不能创建
            raise ParamsException({'code': 1001, 'msg': '账号已存在'})
        # 判断密码是否一致
        code1 = attrs.get('tel_code')
        code2 = cache.get(tel)
        if code1 != code2:
            raise ParamsException({'code': 1002, 'msg': '验证码不正确，请重新获取'})
        return attrs

    def create(self, validated_data):
        # 调用serialzier.save()方法时，被主动调用的create方法
        user_tel = validated_data.get('user_tel')
        # 注册成功给用户一个密码
        # word = ''.join(random.choices('0123456789', k=8))
        word = user_tel[5:12]
        print(word)
        user = UserModel.objects.create(user_tel=user_tel,
                                        password=word)
        return user, word


class LoginSeriaqlizer(serializers.Serializer):
    user_tel = serializers.CharField(max_length=11, min_length=11,
                                     required=True,
                                     error_messages={
                                         'required': '手机号码必填',
                                         'max_length': '请输入正确手机号码',
                                         'min_length': '请输入正确手机号码'
                                     })
    password = serializers.CharField(max_length=12, min_length=6,
                                       required=True,
                                       error_messages={
                                           'required': '账号必填',
                                           'max_length': '账号不能超过10字符',
                                           'min_length': '账号不能短于5字符'
                                       })

    def validate(self, attrs):
        user_tel = attrs.get('user_tel')
        user = UserModel.objects.filter(user_tel=user_tel).first()
        if user:
            password1 = attrs.get('password')
            password2 = user.password
            if password1 == password2:
                return attrs
        raise ParamsException({'code': 1003, 'msg': '账号或密码不正确'})

    def login_user(self, validata_data):
        user_tel = validata_data.get('user_tel')
        user = UserModel.objects.filter(user_tel=user_tel).first()
        # 登录操作，使用redis进行登录标示数据token参数的存储
        # token 是后端返回给前端的登录标示符
        token = uuid.uuid4().hex
        # redis中以字符串格式存储数据，key为token value为用户id值(后端存储)
        cache.set(user_tel, token, timeout=86400)
        # 返回token给前端 存储。
        return token


# 修改密码的serializer
class ChangeSerializer(serializers.Serializer):
    newpassword = serializers.CharField(max_length=12, min_length=6,
                                     required=True,
                                     error_messages={
                                         'required': '账号必填',
                                         'max_length': '账号不能超过10字符',
                                         'min_length': '账号不能短于5字符'
                                     })

    def validate(self, attrs):
        newpassword = attrs.get('newpassword')
        # 没有做新密码校验
        # if PASSWORD_PATTERN.fullmatch(newpassword):
        return attrs
        # raise ParamsException({'code': 1003, 'msg': '密码格式不正确'})


class ChangeInfoSerializer(serializers.ModelSerializer):
    # 修改信息就简单做了，只需要填写信息提交就可以修改

    def validate(self, attrs):
        # 身份证号码验证
        id_card_num = attrs.get('id_card_num')
        if id_card_num:
            user_real_name = attrs.get('user_real_name')
            if not user_real_name:
                raise ParamsException({'code': 1011, 'msg': '请输入真实姓名'})

            url = "http://apis.juhe.cn/idcard/index"
            params = {
                "cardno": id_card_num,  # 身份证号码
                "dtype": "json",  # 返回数据格式：json或xml,默认json
                "key": '73ccd78b80277259772a486f58223c3b',  # 我的的key

            }
            f = requests.post(url=url, params=params)
            res = json.loads(f.text)
            if res:
                error_code = res["error_code"]
                if error_code == 0:
                    # 成功请求
                    print(res["result"])
                else:
                    print("%s:%s" % (res["error_code"], res["reason"]))
            else:
                print("request api error")
        # 只做了身份证号码验证，其他字段没有验证
        # TODO：1。真实姓名验证；2。邮箱验证；3。携程账号密码验证；
        return attrs

    class Meta:
        # 序列化的模型
        model = UserModel
        #  序列化的字段
        fields = ['user_name', 'user_real_name', 'email', 'id_card_num', 'sex', 'ctrip_account', 'ctrip_password']
